<script setup lang="ts">
import { ref, onMounted, h } from 'vue'
import { Card, Table, Input, Button, Space, message, Tree, Tag, Modal, Form, Upload } from 'ant-design-vue'
import { SearchOutlined, ReloadOutlined, PlusOutlined, EditOutlined, DeleteOutlined, KeyOutlined, CheckOutlined, StopOutlined, UploadOutlined, DownloadOutlined } from '@ant-design/icons-vue'
import type { TableColumnsType } from 'ant-design-vue'
import { teacherClassApi } from '@/api/modules/teacherClass'
import type { ClassTreeVO } from '@/types/organization'
import type { UserVO, PageResult } from '@/types/api'
import type { FormInstance } from 'ant-design-vue'
import type { UploadChangeParam } from 'ant-design-vue'

// 加载状态
const loading = ref(false)
const treeLoading = ref(false)

// 班级树数据
const treeData = ref<ClassTreeVO[]>([])
const selectedClass = ref<ClassTreeVO>()

// 表格数据
const tableData = ref<UserVO[]>([])
const pagination = ref({
  current: 1,
  pageSize: 10,
  total: 0,
  showTotal: (total: number) => `共 ${total} 条记录`,
  showSizeChanger: true,
  pageSizeOptions: ['10', '20', '30', '50'],
  // 自定义页码选项的文本
  buildOptionText: (opt: { value: number }) => {
    return `${opt.value} 条/页`
  }
})

// 搜索表单
const searchForm = ref({
  userCode: '',
  realName: ''
})

// 表单相关
const modalVisible = ref(false)
const modalTitle = ref('')
const modalLoading = ref(false)
const formRef = ref<FormInstance>()

// 添加性别常量
const genderOptions = [
  { label: '男', value: 1 },
  { label: '女', value: 2 }
] as const

// 修改表单状态接口
interface FormState {
  id?: number
  userCode: string
  realName: string
  gender: number
  phone: string
  email: string
}

// 修改表单初始值
const formState = ref<FormState>({
  userCode: '',
  realName: '',
  gender: 1, // 默认选择男
  phone: '',
  email: ''
})

// 修改表单校验规则
const rules = {
  userCode: [
    { required: true, message: '请输入学号', trigger: 'blur' },
    { pattern: /^\d{3,12}$/, message: '学号格式不正确，请输入 3-12 位的数字', trigger: 'blur' }
  ],
  realName: [
    { required: true, message: '请输入姓名', trigger: 'blur' },
    { min: 2, max: 20, message: '姓名长度为2-20个字符', trigger: 'blur' }
  ],
  phone: [
    { pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: 'blur' }
  ],
  email: [
    { type: 'email', message: '邮箱格式不正确', trigger: 'blur' }
  ],
  gender: [
    { required: true, message: '请选择性别', trigger: 'change' }
  ]
}

// 组织类型定义
const organizationType = {
  COLLEGE: 1, // 学院
  MAJOR: 2,   // 专业
  CLASS: 3    // 班级
} as const

// 表格列配置
const columns: TableColumnsType = [
  {
    title: '头像',
    dataIndex: 'avatar',
    align: 'center',
    width: 80,
    customRender: ({ record }: { record: UserVO }) => {
      return h('img', {
        src: record.avatar || '/src/assets/logo.png',
        style: {
          width: '40px',
          height: '40px',
          borderRadius: '50%',
          objectFit: 'cover'
        },
        onerror: (e: Event) => {
          const imgElement = e.target as HTMLImageElement
          imgElement.src = '/src/assets/logo.png'
        }
      })
    }
  },
  {
    title: '学号',
    dataIndex: 'userCode',
    align: 'center',
    width: 120
  },
  {
    title: '姓名',
    dataIndex: 'realName',
    align: 'center',
    width: 120
  },
  {
    title: '性别',
    dataIndex: 'gender',
    width: 80,
    align: 'center',
    customRender: ({ text }) => {
      return text === 1 ? '男' : text === 2 ? '女' : '未知'
    }
  },
  {
    title: '手机号',
    align: 'center',
    dataIndex: 'phone',
    width: 150
  },
  {
    title: '邮箱',
    align: 'center',
    dataIndex: 'email'
  },
  {
    title: '状态',
    dataIndex: 'status',
    width: 100,
    align: 'center',
    customRender: ({ record }: { record: UserVO }) => {
      return h(Tag, { color: record.status ? 'success' : 'error' }, () => 
        record.status ? '启用' : '禁用'
      )
    }
  },
  {
    title: '操作',
    width: 250,
    fixed: 'right',
    align: 'center',
    customRender: ({ record }: { record: UserVO }) => {
      return h(Space, {}, () => [
        h(Button, {
          type: 'link',
          onClick: () => handleEdit(record)
        }, () => [
          h(EditOutlined),
          '编辑'
        ]),
        h(Button, {
          type: 'link',
          danger: record.status,
          onClick: () => handleUpdateStatus(record)
        }, () => [
          h(record.status ? StopOutlined : CheckOutlined),
          record.status ? '禁用' : '启用'
        ]),
        h(Button, {
          type: 'link',
          onClick: () => handleResetPassword(record)
        }, () => [
          h(KeyOutlined),
          '重置密码'
        ]),
        h(Button, {
          type: 'link',
          danger: true,
          onClick: () => handleDelete(record)
        }, () => [
          h(DeleteOutlined),
          '删除'
        ])
      ])
    }
  }
]

// 转换树形数据，添加 selectable 属性
interface ProcessedClassTreeVO extends ClassTreeVO {
  selectable: boolean
  children?: ProcessedClassTreeVO[]
}

const processTreeData = (data: ClassTreeVO[]): ProcessedClassTreeVO[] => {
  return data.map(item => ({
    ...item,
    selectable: item.type === organizationType.CLASS,
    children: item.children ? processTreeData(item.children) : undefined
  }))
}

// 查找第一个班级节点
const findFirstClass = (nodes: ClassTreeVO[]): ClassTreeVO | undefined => {
  for (const node of nodes) {
    if (node.type === organizationType.CLASS) {
      return node
    }
    if (node.children?.length) {
      const found = findFirstClass(node.children)
      if (found) return found
    }
  }
  return undefined
}

// 获取班级树
const getClassTree = async () => {
  treeLoading.value = true
  try {
    const data = await teacherClassApi.getClassTree()
    treeData.value = processTreeData(data)
    
    // 如果没有选中的班级，自动选中第一个班级
    if (!selectedClass.value) {
      const firstClass = findFirstClass(treeData.value)
      if (firstClass) {
        selectedClass.value = firstClass
        getStudentList() // 加载学生列表
      }
    }
  } catch (error) {
    console.error('获取班级树失败:', error)
    message.error(error||'获取班级树失败')
  } finally {
    treeLoading.value = false
  }
}

// 获取学生列表
const getStudentList = async () => {
  if (!selectedClass.value?.id) return
  
  loading.value = true
  try {
    const  data  = await teacherClassApi.getClassStudents(
      selectedClass.value.id,
      {
        userCode: searchForm.value.userCode,
        realName: searchForm.value.realName,
        page: pagination.value.current - 1,
        size: pagination.value.pageSize
      }
    )
    
    if (data) {
      tableData.value = data.content
      pagination.value = {
        ...pagination.value,
        total: data.totalElements
      }
    }
  } catch (error) {
    console.error('获取学生列表失败:', error)
    message.error(error||'获取学生列表失败')
  } finally {
    loading.value = false
  }
}

// 处理班级选择
const handleClassSelect = (selectedKeys: string[], info: any) => {
  if (selectedKeys.length > 0 && info.node.type === organizationType.CLASS) {
    selectedClass.value = info.node
    // 重置分页和搜索条件
    pagination.value.current = 1
    searchForm.value = {
      userCode: '',
      realName: ''
    }
    getStudentList()
  }
}

// 处理搜索
const handleSearch = () => {
  pagination.value.current = 1
  getStudentList()
}

// 处理重置
const handleReset = () => {
  searchForm.value = {
    userCode: '',
    realName: ''
  }
  handleSearch()
}

// 处理表格变化
const handleTableChange = (pag: any) => {
  pagination.value.current = pag.current
  pagination.value.pageSize = pag.pageSize
  getStudentList()
}

// 处理新增
const handleAdd = () => {
  formState.value = {
    userCode: '',
    realName: '',
    gender: 1,
    phone: '',
    email: ''
  }
  modalTitle.value = '新增学生'
  modalVisible.value = true
}

// 处理编辑
const handleEdit = (record: UserVO) => {
  formState.value = {
    id: record.id,
    userCode: record.userCode,
    realName: record.realName,
    gender: record.gender,
    phone: record.phone || '',
    email: record.email || ''
  }
  modalTitle.value = '编辑学生'
  modalVisible.value = true
}

// 处理提交
const handleSubmit = async () => {
  if (!formRef.value) return
  if (!selectedClass.value?.id) {
    message.error('请先选择班级')
    return
  }

  try {
    await formRef.value.validate()
    modalLoading.value = true

    const params = {
      ...formState.value,
      departmentId: selectedClass.value.id
    }

    if (formState.value.id) {
      await teacherClassApi.updateStudent(
        selectedClass.value.id,
        formState.value.id,
        params
      )
      message.success('更新成功')
    } else {
      await teacherClassApi.createStudent(selectedClass.value.id, params)
      message.success('创建成功')
    }

    modalVisible.value = false
    getStudentList()
  } catch (error) {
    console.error('提交失败:', error)
    message.error(error||'提交失败')
  } finally {
    modalLoading.value = false
  }
}

// 处理删除
const handleDelete = (record: UserVO) => {
  Modal.confirm({
    title: '确认删除',
    content: `确定要删除学生"${record.realName}"吗？`,
    okText: '确认',
    okType: 'danger',
    cancelText: '取消',
    async onOk() {
      try {
        if (!selectedClass.value?.id) return
        await teacherClassApi.deleteStudent(selectedClass.value.id, record.id)
        message.success('删除成功')
        getStudentList()
      } catch (error) {
        console.error(error)
        message.error(error||'删除失败')
      }
    }
  })
}

// 处理状态更新
const handleUpdateStatus = (record: UserVO) => {
  Modal.confirm({
    title: '确认操作',
    content: `确定要${record.status ? '禁用' : '启用'}学生"${record.realName}"吗？`,
    okText: '确认',
    cancelText: '取消',
    async onOk() {
      try {
        if (!selectedClass.value?.id) return
        await teacherClassApi.updateStudentStatus(
          selectedClass.value.id,
          record.id,
          !record.status
        )
        message.success('操作成功')
        getStudentList()
      } catch (error) {
        console.error(error)
        message.error(error||'操作失败')
      }
    }
  })
}

// 处理重置密码
const handleResetPassword = (record: UserVO) => {
  Modal.confirm({
    title: '确认重置密码',
    content: `确定要重置学生"${record.realName}"的密码吗？`,
    okText: '确认',
    cancelText: '取消',
    async onOk() {
      try {
        if (!selectedClass.value?.id) return
        await teacherClassApi.resetStudentPassword(
          selectedClass.value.id,
          record.id
        )
        message.success('重置成功')
      } catch (error) {
        console.error(error)
        message.error(error||'重置失败')
      }
    }
  })
}

// 自定义上传方法
const customRequest = async (options: any) => {
  console.log('自定义上传方法被调用:', {
    fileName: options.file.name,
    fileType: options.file.type,
    fileSize: options.file.size
  })
  
  const { file, onSuccess, onError } = options
  try {
    // 检查文件类型
    if (!file.type.includes('sheet') && !file.name.endsWith('.xls') && !file.name.endsWith('.xlsx')) {
      console.warn('文件类型不正确:', file.type)
      throw new Error('只能上传 Excel 文件')
    }
    // 检查文件大小（假设限制为10MB）
    if (file.size > 10 * 1024 * 1024) {
      console.warn('文件过大:', file.size)
      throw new Error('文件大小不能超过10MB')
    }

    if (!selectedClass.value?.id) {
      throw new Error('请先选择班级')
    }

    console.log('开始导入文件...')
    loading.value = true

    try {
      const result = await teacherClassApi.importStudents(selectedClass.value.id, file)
      console.log('导入结果:', result)

      // 直接处理返回的数据
      const importResult = result.data || result
      message.success({ content: `导入成功！成功: ${importResult.success}条, 失败: ${importResult.failed}条` })
      
      if (importResult.errorMessages?.length > 0) {
        Modal.warning({
          title: '导入警告',
          content: h('div', {}, [
            h('p', '以下数据导入失败：'),
            h('ul', {}, importResult.errorMessages.map(msg => 
              h('li', { style: { color: '#ff4d4f' } }, msg)
            ))
          ])
        })
      }
      
      // 刷新列表
      getStudentList()
      onSuccess()
    } catch (error: any) {
      console.error('导入失败:', error)
      onError(error)
      throw error
    } finally {
      loading.value = false
    }
  } catch (error: any) {
    console.error('文件验证或导入失败:', error)
    message.error({ content: error.message || '导入失败' })
    onError(error)
  }
}

// 处理文件导入
const handleImport = async (info: UploadChangeParam) => {
  console.log('文件状态变更:', info)
  // 这里只处理错误状态，实际的导入逻辑已经移到 customRequest 中
  if (info.file.status === 'error') {
    console.error('文件上传失败')
    message.error({ content: '文件上传失败' })
  }
}

// 处理导出
const handleExport = async () => {
  if (!selectedClass.value?.id) {
    message.warning({ content: '请先选择班级' })
    return
  }
  
  try {
    const blob = await teacherClassApi.exportStudents(selectedClass.value.id)
    
    // 创建下载链接并设置文件名
    const fileName = `${selectedClass.value.name}-学生名单.xlsx`
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = fileName
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
    message.success({ content: '导出成功' })
  } catch (error: any) {
    console.error('导出失败:', error)
    message.error({ content: error.message || '导出失败' })
  }
}

// 下载模板
const handleDownloadTemplate = async () => {
  try {
    const blob = await teacherClassApi.downloadStudentTemplate()
    
    // 创建下载链接
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = '学生导入模板.xlsx'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
    message.success({ content: '下载成功' })
  } catch (error: any) {
    console.error('下载失败:', error)
    message.error({ content: error.message || '下载失败' })
  }
}

// 初始化
onMounted(() => {
  getClassTree()
})
</script>

<template>
  <div class="class-manage">
    <Card class="class-tree" :loading="treeLoading">
      <a-tree
        :tree-data="treeData"
        :defaultExpandAll="true"
        :selectedKeys="selectedClass ? [selectedClass.id] : []"
        :fieldNames="{
          title: 'name',
          key: 'id'
        }"
        @select="handleClassSelect"
      >
        <template #title="{ name, type }">
          <span :class="{ 'tree-node-class': type === organizationType.CLASS }">
            {{ name }}
          </span>
        </template>
      </a-tree>
    </Card>
    
    <Card class="class-content">
      <template #title>
        <span>{{ selectedClass?.name || '请选择班级' }}</span>
      </template>
      
      <!-- 搜索区域 -->
      <div class="table-search">
        <div class="search-left">
          <Space>
            <Input
              v-model:value="searchForm.userCode"
              placeholder="学号"
              allowClear
            />
            <Input
              v-model:value="searchForm.realName"
              placeholder="姓名"
              allowClear
            />
            <Button type="primary" @click="handleSearch">
              <template #icon><SearchOutlined /></template>
              搜索
            </Button>
            <Button @click="handleReset">
              <template #icon><ReloadOutlined /></template>
              重置
            </Button>
          </Space>
        </div>
        <div class="search-right">
          <Space>
            <Upload
              :customRequest="customRequest"
              :showUploadList="false"
              :multiple="false"
              accept=".xlsx,.xls"
              @change="handleImport"
            >
              <Button>
                <template #icon><UploadOutlined /></template>
                导入学生
              </Button>
            </Upload>
            <Button @click="handleExport">
              <template #icon><DownloadOutlined /></template>
              导出学生
            </Button>
            <Button @click="handleDownloadTemplate">
              <template #icon><DownloadOutlined /></template>
              下载模板
            </Button>
            <Button type="primary" @click="handleAdd">
              <template #icon><PlusOutlined /></template>
              新增学生
            </Button>
          </Space>
        </div>
      </div>
      
      <!-- 表格 -->
      <Table
        row-key="id"
        :columns="columns"
        :data-source="tableData"
        :pagination="pagination"
        :loading="loading"
        @change="handleTableChange"
      />
    </Card>
  </div>
  
  <!-- 添加表单弹窗 -->
  <Modal
    v-model:visible="modalVisible"
    :title="modalTitle"
    :maskClosable="false"
    :confirmLoading="modalLoading"
    @ok="handleSubmit"
    ok-text="确定",
    cancel-text="取消"
  >
    <Form
      ref="formRef"
      :model="formState"
      :rules="rules"
      :label-col="{ span: 4 }"
      :wrapper-col="{ span: 18 }"
    >
      <Form.Item label="学号" name="userCode">
        <Input v-model:value="formState.userCode" placeholder="请输入学号" />
      </Form.Item>
      <Form.Item label="姓名" name="realName">
        <Input v-model:value="formState.realName" placeholder="请输入姓名" />
      </Form.Item>
      <Form.Item label="性别" name="gender">
        <a-radio-group v-model:value="formState.gender">
          <a-radio v-for="opt in genderOptions" :key="opt.value" :value="opt.value">
            {{ opt.label }}
          </a-radio>
        </a-radio-group>
      </Form.Item>
      <Form.Item label="手机号" name="phone">
        <Input v-model:value="formState.phone" placeholder="请输入手机号" />
      </Form.Item>
      <Form.Item label="邮箱" name="email">
        <Input v-model:value="formState.email" placeholder="请输入邮箱" />
      </Form.Item>
    </Form>
  </Modal>
</template>

<style lang="less" scoped>
.class-manage {
  display: flex;
  height: 100%;
  
  .class-tree {
    width: 280px;
    margin-right: 16px;
    
    :deep(.ant-card-body) {
      height: calc(100% - 57px);
      padding: 0;
      overflow: auto;
    }

    :deep(.tree-node-class) {
      cursor: pointer;
      color: #1890ff;

      &:hover {
        text-decoration: underline;
      }
    }

    :deep(.ant-tree-node-content-wrapper) {
      &:not(.ant-tree-node-selected) {
        &:hover {
          background-color: transparent;
        }
      }
    }
  }
  
  .class-content {
    flex: 1;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    
    .table-search {
      margin-bottom: 16px;
      display: flex;
      justify-content: space-between;
      align-items: center;

      .search-left {
        // 左侧搜索区域样式
      }

      .search-right {
        display: flex;
        gap: 8px;
        
        .ant-btn {
          margin-left: 0;
        }
      }
    }

    :deep(.ant-card-body) {
      flex: 1;
      overflow: hidden;
      display: flex;
      flex-direction: column;

      .ant-table-wrapper {
        flex: 1;
        overflow: hidden;
      }
    }

    :deep(.ant-table) {
      .ant-table-row {
        td {
          padding: 12px 8px;
          vertical-align: middle;
        }
      }

      .avatar-column {
        img {
          display: block;
          border: 1px solid #f0f0f0;
          transition: all 0.3s;

          &:hover {
            transform: scale(1.1);
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
          }
        }
      }
    }
  }
}
</style> 